#pragma once

#include "util.hpp"
#include <unordered_map>
#include <mutex>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wwserver_t;

class OlineUser_Manager
{
private:
    std::mutex _mutex;                                                    // 互斥锁
    std::unordered_map<uint64_t, wwserver_t::connection_ptr> _hall_users; // 建立大厅用户，通过id建立的通信连接
    std::unordered_map<uint64_t, wwserver_t::connection_ptr> _room_users; // 建立房间用户，通过id建立的通信连接
public:
    // websocket连接建立时，才会增加大厅用户 & 房间用户的在线用户管理
    void enter_game_hall(uint64_t uid, wwserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_users.insert(std::make_pair(uid, conn));
    }

    void enter_game_room(uint64_t uid, wwserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_users.insert(std::make_pair(uid, conn));
    }

    // websocket连接断开时，才会减少大厅用户 & 房间用户的在线用户管理
    void exit_game_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_users.erase(uid);
    }

    void exit_game_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_users.erase(uid);
    }

    // 判断用户是否在房间 & 大厅 中
    bool is_in_hall_user(uint64_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_users.find(id);
        if (it == _hall_users.end())
        {
            return false;
        }

        return true;
    }

    bool is_in_room_user(uint64_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_users.find(id);
        if (it == _room_users.end())
        {
            return false;
        }

        return true;
    }

    // 通过用户id获取大厅用户 & 房间用户管理的通信连接
    wwserver_t::connection_ptr get_from_hall_con(uint64_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_users.find(id);
        if (it == _hall_users.end())
        {
            return wwserver_t::connection_ptr();
        }

        return it->second;
    }

    wwserver_t::connection_ptr get_from_room_con(uint64_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_users.find(id);
        if (it == _room_users.end())
        {
            return wwserver_t::connection_ptr();
        }

        return it->second;
    }
};
